using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using Microsoft.StylusInput;
using Microsoft.StylusInput.PluginData;
using Microsoft.Ink;
using System.Threading;

namespace MultiLayer
{
    public class Canvas : UserControl
    {
        public Canvas()
        {
            // set the background color
            this.BackColor = Color.White;

            // set the border
            this.BorderStyle = BorderStyle.FixedSingle;

            // set the styles to make this canvas double buffered
            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.UserPaint, true);

            // initialize the layers
            //this.mForegroundLayer = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
            //this.mBackgroundLayer = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);

            this.mStylus = new RealTimeStylus(this, true);

            this.mTools = new Dictionary<string, Tool>();
            this.mTools["Pen"] = new PenTool(this);
            this.mTools["Select"] = new SelectTool(this);

            this.mSemaphore = new Semaphore(1, 1);
        }

        public Tool Tool
        {
            get
            {
                return this.mCurrentTool;
            }
            set
            {
                if (this.mSemaphore.WaitOne())
                {
                    this.mStylus.Enabled = false;

                    // set the current tool
                    this.mCurrentTool = value;

                    // set the cursor depending on the current tool
                    this.Cursor = value.Cursor;

                    // add tool to stylus

                    this.mStylus.AsyncPluginCollection.Clear();
                    this.mStylus.AsyncPluginCollection.Add(this.mCurrentTool);
                    this.mStylus.Enabled = true;

                    this.mSemaphore.Release();
                }
            }
        }

        public Tool GetTool(string pToolName)
        {
            return this.mTools[pToolName];
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            // draw the layers
            //e.Graphics.DrawImage(this.mBackgroundLayer, new Point(0, 0));
            //e.Graphics.DrawImage(this.mForegroundLayer, new Point(0, 0));
            if (this.mSemaphore.WaitOne())
            {
                Graphics graphics = e.Graphics;
                //graphics.SetClip(e.ClipRectangle);
                graphics.SmoothingMode = SmoothingMode.AntiAlias;
                graphics.PageScale = 0.01f;
                graphics.PageUnit = GraphicsUnit.Millimeter;
                
                Screen.Current.Draw(graphics);

                this.mSemaphore.Release();
            }
            // call the base
            base.OnPaint(e);
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            // initialize the layers
            //if ((this.mForegroundLayer.Width != this.ClientSize.Width) ||
            //    (this.mForegroundLayer.Height != this.ClientSize.Height))
            //{
            //    this.mForegroundLayer = new Bitmap(this.ClientSize.Width, this.ClientSize.Height, PixelFormat.Format32bppArgb);
            //    this.mBackgroundLayer = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);

            //    Graphics.FromImage(this.mForegroundLayer).Clear(Color.FromArgb(0, Color.White));
            //}

            // call the base
            base.OnSizeChanged(e);
        }

        //private Bitmap mForegroundLayer;
        //private Bitmap mBackgroundLayer;
        private Tool mCurrentTool;
        private Dictionary<string, Tool> mTools;
        private RealTimeStylus mStylus;
        private Semaphore mSemaphore;
    }
}
